/**
 * 
 */
package fr.ece.ing4.si.mc.multiThreading;

import java.util.Random;
import java.util.concurrent.Callable;

import fr.ece.ing4.si.mc.MonteCarlo.MultiMonteCarloController;


/**
 * @author Cesar Berezowski, Gaspard Peyrot
 */
public class MultiMonteCarloMethod implements Callable<Double> {

	private int thread;
	private int z;
	private double drift;
	private double vSqrdt;
	private double x;
	private double st;
	private int nSteps;
	public MultiMonteCarloController c;
	
	/**
	 * Constructor
	 * @param thread number of the thread
	 * @param z flag for calling or putting
	 * @param drift value of drift
	 * @param vSqrdt
	 * @param x strike price
	 * @param nSteps number of steps
	 * @param st underlying price
	 * @param c pointer on the controller
	 */
	public MultiMonteCarloMethod(int thread, int z, double drift, double vSqrdt, double x, int nSteps, double st, MultiMonteCarloController c) {

		this.thread = thread;
		this.drift = drift;
		this.vSqrdt = vSqrdt;
		this.x = x;
		this.nSteps = nSteps;
		this.st = st;
		this.z = z;
		this.c = c;
	}

	/**
	 * Computation
	 */
	@Override
	public Double call() throws Exception {
		
		Random rand = new Random();
		double sum = 0.0;
		
		for(int i = 0; i < nSteps; i++){
			st = st * Math.exp(drift + vSqrdt * rand.nextGaussian());
		}
		
		sum = Math.max(z * (st - x), 0.0);
		synchronized(MultiMonteCarloController.class){
			c.updateProgress();
		}
		System.out.println("Thread " + thread + " : sum = " + sum);
		
		return sum;
	}

}
